#pragma once

#include "Generics.h"
#include "ServerLogic.h"
#include <string>
#include <vector>
#include "dirent.h"
#include "sys/stat.h"

#define DEFAULT_PATH "mails\\"
namespace StorageEngine {

	class IStorageEngine {
	public:
		virtual bool HasAccount(std::string user) = 0;
		virtual ServerLogic::UserAccount * GetAccount(std::string user) = 0;
	};

	class Storage {
		static Storage * _instance;
		Storage();
		std::vector <IStorageEngine *> _engines;
	public:
		static Storage * Instance();
		ServerLogic::UserAccount * GetAccount(std::string user);
	};

	class StorageException : public Generic::Exception {
	public:
		StorageException(std::string message);
	};

	class StorageAmbiguousAccountException : public StorageException {
	public:
		StorageAmbiguousAccountException(std::string message);
	};

	class StorageNoAccountException : public StorageException {
	public:
		StorageNoAccountException(std::string);
	};

	/****************************
		Engines
	****************************/
	class DummyMailManager : public ServerLogic::IMailManager {
		std::vector <std::string> _mails;
		std::vector <bool> _present;
		bool _locked;
	public:
		DummyMailManager();
		DummyMailManager(std::string user );
		ServerLogic::MailList ListAll();
		ServerLogic::MailStub List(int msg);
		ServerLogic::MaildropInfo Stat();
		ServerLogic::Mail Retrieve(int msg);
		void Delete(int msg);
		void Reset();
		void AcquireLock();
		void ReleaseLock();
		void UpdateMaildrop();
	};
	class DummyStorageEngine : public IStorageEngine {
	public:
		bool HasAccount(std::string user);
		ServerLogic::UserAccount * GetAccount(std::string user);
	};	
	
	class MailManager : public ServerLogic::IMailManager {
		std::vector <std::string> _mails;
		std::vector <bool> _present;
		bool _locked;
	public:
		MailManager();
		ServerLogic::MailList ListAll();
		ServerLogic::MailStub List(int msg);
		ServerLogic::MaildropInfo Stat();
		ServerLogic::Mail Retrieve(int msg);
		void Delete(int msg);
		void Reset();
		void AcquireLock();
		void ReleaseLock();
		void UpdateMaildrop();
	};

	class StorageEngine : public IStorageEngine {
	public:
		bool HasAccount(std::string user);
		ServerLogic::UserAccount * GetAccount(std::string user);
	};
};